﻿#include <iostream>
#include<vector>
#include<map>
#include<curl/curl.h>
#include<regex>
#include<filesystem>
#include<fstream>
using namespace std;

const static string URL = "http://ssr1.scrape.center";
string fileName;
const static int PAGE = 10;
const static string PATH = "./movies";

size_t writeCallback(void* contents, size_t size, size_t nmemb, std::string* output)
{
	size_t totalSize = size * nmemb;
	output->append((char*)contents, totalSize);
	return totalSize;
}

//编写一个发起请求的函数，接收返回函数
string request(const string& ulr, map<string, string>headers = map<string, string>())
{
	SetConsoleOutputCP(65001);
	CURL* curl;
	CURLcode statusCode;
	string htmlData;
	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();
	if (curl) {
		// 设置要抓取的⽹⻚地址
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
		//判断是否有cookies
		if (headers.find("cookies") != headers.end())
		{
			curl_easy_setopt(curl, CURLOPT_COOKIE, headers["cookies"].c_str());
		}

		curl_easy_setopt(curl, CURLOPT_URL, URL.c_str());
		// 设置回调函数，⽤于处理获取到的响应数据
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &htmlData);
		// 执⾏ HTTP 请求
		auto res = curl_easy_perform(curl);
		if (res != CURLE_OK)
		{
			std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
		}
		// 输出获取到的⽹⻚内容
		//cout << htmlData << std::endl;

		// 清理 CURL 实例
		curl_easy_cleanup(curl);
	}
	else {
		std::cerr << "curl_easy_init() failed." << std::endl;
		return htmlData;
	}

	curl_global_cleanup();

	return htmlData;
}

void GetURL(const string& htmlDate)
{
	string url;
	string html;
	smatch result;
	regex reg("/detail/\\d+");
	for (int page = 1; page <= PAGE; page++)
	{
		url = URL + "/page/" + to_string(page);
		html = request(url);
		auto end_it = sregex_iterator();
		sregex_iterator it(htmlDate.begin(), htmlDate.end(), reg);
		for (; it != end_it; it++)
		{
			result = *it;
			cout << it->str() << "\n";
			
		}
	}
	
}

vector<string> findAll(const string html, regex reg)
{
	auto end_it = sregex_iterator();
	smatch result;
	vector<string> vt;
	sregex_iterator it(html.begin(), html.end(), reg);
	for (; it != end_it; it++)
	{
		result = *it;
		cout << it->str() << "\n";

	}

	return vt;

}

//string vectorString(vector<string>& vt)
//{
//	ostringstream oss;
//	for (auto& w : vt)
//	{
//		oss << w << " ";
//	}
//	return oss.str();
//}

map<string,string> ParseDetailPage(const string& url)
{	
	map<string, string>  ResultMap;
	string html = request(url);
	regex RegTitle(">(.*)</h2>");
	smatch ResultTitle,ResultCategories, ResultArea, ResultTime, ResultPublish, ResultDrama,ResultScore;
	regex_search(html, ResultTitle, RegTitle);
	cout << ResultTitle.str() << "\n";

	regex RegCategories("<span>(.*)</span>");
	vector<string> vt = findAll(html, RegCategories);
	vt.pop_back();

	regex RegArea(">[^x00-xff/]</span>");
	regex_search(html, ResultArea, RegArea);
	cout << ResultArea[1].str() << "\n";

	regex RegTime(">(\\d+).*</span>");
	regex_search(html, ResultTime, RegTime);
	cout<< ResultTime[1].str() << "\n";

	regex RegPublish("\\d+-\\d+-\\d+");
	regex_search(html, ResultPublish, RegTime);
	cout << ResultPublish[1].str() << "\n";

	regex RegDrama(">\\s+(.*)\\s+</p>");
	regex_search(html, ResultDrama, RegDrama);
	cout << ResultDrama[1].str() << "\n";

	regex RegScore("\\d+\\.\\d+");
	regex_search(html, ResultScore, RegScore);
	cout << ResultScore[1].str() << "\n";

	ResultMap["title"] = ResultTime[1].str();
	//ResultMap["categories"] = vectorString(vt);
	ResultMap["area"] = ResultArea[1].str();
	ResultMap["time"] = ResultTime[1].str();
	ResultMap["publis"] = ResultPublish[1].str();
	ResultMap["drama"] = ResultDrama[1].str();
	ResultMap["Score"] = ResultScore[1].str();

	return ResultMap;		
}
string ConvertUTF8toGBK(const string& str) 
{
	int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
	std::wstring wstr(len, L'\0');
	MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &wstr[0], len);
	len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
	std::string ret(len, '\0');
	WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &ret[0], len, NULL, NULL)
		;
	return ret;
}

int main()
{
	SetConsoleOutputCP(65001);
	if (!filesystem::exists(PATH))
	{
		filesystem::create_directory(PATH);
	}
	string html = request("http://ssr1.scrape.center/page/2");
	cout << html << "\n";
	string url;
	vector<string> URL_VT;
	map<string, string>resultMap;
	while (!URL_VT.empty())
	{
		url = URL_VT.back();
		URL_VT.pop_back();
		resultMap = ParseDetailPage(url);
		fileName = PATH + "/" + resultMap["title"] + ".txt";

		fstream fout(fileName,ios::out);
		for (auto& m : resultMap)
		{
			fout << m.first << " " << m.second << "\n";
		}

	}
	
	

}

